package snapex.core.security;

import java.security.interfaces.RSAPublicKey;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.oauth2.provider.authentication.TokenExtractor;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class JwtVerifierConfiguration {
	@Value("${snapex.security.keyStorePassword}")
	String keyStorePassword;
	
	@Value("${snapex.security.keyStorePath}")
	String keyStorePath;	
	
	@Value("${snapex.security.keyStoreAlias}")
	String keyStoreAlias;	
	
	@Bean("JwtSignatureVerifier")
	public SignatureVerifier signatureVerifier() {
		
		Resource keyStoreResource = null;
		if(keyStorePath.startsWith("classpath:")) {
			keyStoreResource = new ClassPathResource(keyStorePath.replaceFirst("classpath:",""));
		}else {
			keyStoreResource = new FileSystemResource(keyStorePath);
		}
		
		KeyStoreKeyFactory factory = new KeyStoreKeyFactory(keyStoreResource,keyStorePassword.toCharArray());
				
		return new RsaVerifier((RSAPublicKey)factory.getKeyPair(keyStoreAlias).getPublic());
	}
	
	@Bean("JwtTokenExtractor")
	public TokenExtractor tokenExtractor() {
		return new BearerTokenExtractor() {
			@Override
			protected String extractHeaderToken(HttpServletRequest request) {
				
				String token = request.getHeader("WechatAccessToken"); 
				if(StringUtils.isEmpty(token)) {
					token = request.getParameter("access_token");
					
					if(StringUtils.isEmpty(token)) {
						token = super.extractHeaderToken(request);
					}
				}				
				
				return token;
				
			}
		};
	}	
}
